# 面向对象编程
# 类class:我们将具有相同属性和功能的物体，归纳为一“类”。类是一个抽象概念，它是没实体的。
# 对象0bject:根据类具象化出现一实体
# 在人认识世界时，先有对象，再把对象进行分类
# 在神创造世界时，先定义类，再按类实例化对象
#1、定义类
class Person:       #定义Person类，类名一般首字母大写
    name='大明'       #定义类的成员属性，name和color
    color='Yellow'
    def talk(self):     #定义类的成员方法，talk和hobby
        print(f'我的名字是{self.name}，皮肤颜色是{self.color}')
    def hobby(self):
        print('我的爱好是看书与学习。')
#2、对象的实例化
    #类只是一个抽象概念，它默认不执行任何动作
    #可以根据类实例化出对象来
p1=Person()     #通过Person类实例化出对象p1
p1.name='小红'    #对象p1可以对Person类中的成员属性进行使用和修改
p1.talk()       #对象p1可以对Person类中的成员方法进行使用

p2=Person()     #通过Person类实例化出对象p2
p2.talk()       #p1修改的成员属性只针对p1有效，对p2没有任何影响
'''Person类是一个主本，p1和p2都是副本，玩家1和玩家2副本内容一样，但进度独立。'''

'''
class School():
    dept=10
    sumclass=100
    def talk(self):
        print(f'我们学校有{self.dept}个系')
    def people(self):
        print(f'我们每个系每个班有{self.sumclass}人')
s1=School()
s1.talk()

s2=School()
s2.dept=16
s2.sumclass=44
s2.talk()
#s2.sumclass()
'''

class Father:
    name='大明'
    color='Yellow'
    def talk(self):
        print(f'我的名字是{self.name}，皮肤颜色是{self.color}')
    def hobby(self):
        print('我的爱好是看书与学习。')
class Son(Father):      #定义子类son，指明父类是father
    name = '小明'
    def hobby(self):
        print('我的爱好是唱、跳、rap、篮球')
f1=Father()
f1.talk()
f1.hobby()
    #子类没有talk方法，可以继承父类的talk方法，减少了代码的重复性
    #子类有hobe方法，可以重写父类的hobe方法，保留了代码的多态性和灵活性
    #子类有name属性，可以用自己的属性
    #子类没有color属性，可以继承父类的color属性
s1=Son()
s1.talk()
s1.hobby()

'''
#4、构造函数__init_
#__init__是类的构造函数，也称初始化函数
#在实例化对象的时候，就会自动执行构造函数__init__
class Example4:
    def __init__(self):
        print('我是构造函数')
    def f1(self):
        print('我的方法1')
e=Example4()    #实例化对象时自动执行构造函数__init__，但不会执行f1
'''
#构造函数的形参，就是类的形参
class E:        #类没有写形参
    def __init__(self,a,b):      #构造函数写了形参
        print(f'a={a},b={b}')
e=E(6,9)        #实例化对象时，就必须给构造函数传递实参a和b

class E:
    c=99
    def __init__(self,a,b):
        print(f'a={a},b={b}')
        self.a = a
        self.b = b
    def f1(self):
        print(f'a={self.a},b={self.b},c={self.c}')
e=E(5,8)
e.f1()

#练习1:写一个类rectangle，接受两个形参width和height#它具备两项功能，求周长perimeter和求面积area
#要求输入5和8，输出矩形的周长是26，矩形的面积是40
#要求输入5和10，输出矩形的面积是50
class Rectangle:
    def __init__(self,width,height):
        self.width=width
        self.height=height
    def perimeter(self):
        perimeter=(self.width+self.height)*2
        return perimeter
    def area(self):
        area=self.width*self.height
        return area
j1=Rectangle(5,8)
print(f'矩形1的周长为:{j1.perimeter()}'+','+f'矩形1的面积为:{j1.area()}')

j2=Rectangle(5,10)
print(f'矩形2的面积为:{j1.area()}')


#练习2：写一个类Class班级
    #初始化有3名学生{'1':'孔明','2':'孔暗','3':'孔子'}
    #写一个方法show_stu，展示目前所有的学生
    #写一个方法add_stu，接受2个参数sid和sname，把学生信息添加到学生表中
    #写一个方法del_stu，接受1个参数sid把指定的学生删掉(不考虑sid不存在的情况)
class Class:
    def __init__(self):
        self.stu={'1':'孔明','2':'孔暗','3':'孔子'}
    def show_stu(self):
        print(self.stu)
    def add_stu(self,sid,sname):
        self.sid=sid
        self.sname=sname
        self.stu[sid]=sname
    def del_stu(self,sid):
        del self.stu[sid]
    #1、查看所有的学生信息
s1=Class()
s1.show_stu()
    #2、添加4号学生孔融
s1.add_stu('4','孔融')
    #3、查看所有的学生信息
s1.show_stu()
    #4、删除1号学生
s1.del_stu('1')
    #5、查看所有的学生信息
s1.show_stu()





